package cn.siat.gene.service.impl;

import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import cn.siat.common.core.exception.ServiceException;
import cn.siat.common.security.utils.SecurityUtils;
import cn.siat.gene.domain.MinioFile;
import cn.siat.gene.domain.ProgrammeFile;
import cn.siat.gene.domain.dto.ProgrammeFileDto;
import cn.siat.gene.domain.dto.ProgrammeFileQueryParam;
import cn.siat.gene.domain.vo.ProgrammeFileVO;
import cn.siat.gene.mapper.MinioFileMapper;
import cn.siat.gene.mapper.ProgrammeFileMapper;
import cn.siat.gene.mapper.ProgrammeFileMinioMapper;
import cn.siat.gene.model.MinioChunk;
import cn.siat.gene.service.IGenomeDataService;
import cn.siat.gene.service.IProgrammeFileService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jodd.util.MathUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
public class ProgrammeFileServiceImpl extends ServiceImpl<ProgrammeFileMapper, ProgrammeFile> implements IProgrammeFileService {

    @Resource
    private ProgrammeFileMapper programmeFileMapper;
    @Resource
    private MinioFileMapper minioFileMapper;


    @Override
    public List<ProgrammeFileVO> queryPageList(ProgrammeFileQueryParam queryParams) {
        String genomeDataName = queryParams.getName();
        String userId = SecurityUtils.getUserId();
        queryParams.setCreateBy(userId);
        if (StringUtils.hasLength(genomeDataName)) {
            queryParams.setName(genomeDataName.trim());
        }
        List<ProgrammeFileVO> list = programmeFileMapper.queryProgrammeList(queryParams);
        for (ProgrammeFileVO vo : list) {
            String percentage = getPercentage(vo.getMd5());
            if (Integer.parseInt(percentage) == -1 && vo.getStatus() != 3) {
                programmeFileMapper.updateById(new ProgrammeFile().setId(Long.valueOf(vo.getId())).setStatus(String.valueOf(3)));
                vo.setPercentage(0);
                continue;
            } else if(vo.getStatus() == 3){
                vo.setPercentage(0);
                continue;
            }else if (Integer.parseInt(percentage) == 100 && vo.getStatus() != 2) {
                programmeFileMapper.updateById(new ProgrammeFile().setId(Long.valueOf(vo.getId())).setStatus(String.valueOf(2)));
                vo.setPercentage(100);
                continue;
            } else if (Integer.parseInt(percentage) == 0) {
                //如果进度为零时间小于10分钟，并且状态为上传中或者暂停的文件，返回进度0
                if(Math.abs(DateUtil.between(vo.getUpdateTime(), new Date(), DateUnit.MINUTE)) < 10 && (vo.getStatus() == 1 || vo.getStatus() == 4)){
                    vo.setPercentage(Integer.parseInt(percentage));
                    continue;
                }else{
                    programmeFileMapper.updateById(new ProgrammeFile().setId(Long.valueOf(vo.getId())).setStatus(String.valueOf(3)));
                    vo.setPercentage(0);
                    continue;
                }
            }
            vo.setPercentage(Integer.valueOf(percentage));
        }
        return list;
    }


    @Override
    public int insertProgrammeFile(ProgrammeFileDto programmeFileDto) {
        String md5 = programmeFileDto.getMd5();
        String fileName = programmeFileDto.getName();
        String type = programmeFileDto.getType();
        long size = programmeFileDto.getSize();
        String tab = programmeFileDto.getTab();
        if (md5 == null) {
            throw new ServiceException("请上传文件");
        }

        if (fileName == null || fileName.length() == 0) {
            throw new ServiceException("文件不存在");
        }
        if (!"1".equals(type) && !"2".equals(type) && !"3".equals(type) && !"4".equals(type)) {
            throw new ServiceException("上传文件类型错误");
        }
        if (size < 1) {
            throw new ServiceException("请上传文件");
        }
        MinioFile one = minioFileMapper.getByMd5(md5);

        ProgrammeFile programmeFile = new ProgrammeFile();
        programmeFile.setName(fileName);
        programmeFile.setTab(tab);
        programmeFile.setType(type);
        programmeFile.setCreateTime(new Date());
        programmeFile.setUpdateTime(new Date());
        // 上传中状态
        if (one != null && one.getIsComplete() == 1) {
            programmeFile.setStatus("2");
        } else {
            programmeFile.setStatus("1");
        }
        programmeFile.setSize(size);
        programmeFile.setMd5(md5);
        programmeFile.setCreateBy(SecurityUtils.getUserId());

        return programmeFileMapper.insert(programmeFile);

    }

    @Override
    public List<String> listTab() {
        return programmeFileMapper.selectTabs(SecurityUtils.getUserId());
    }

    @Override
    public int deleteProgrammeFileById(ProgrammeFile programmeFile) {
        if (programmeFileMapper.selectById(programmeFile.getId()) == null) {
            throw new ServiceException("删除文件不存在！");
        }

        return programmeFileMapper.deleteById(programmeFile);
    }

    @Override
    public String getPercentage(String md5) {
        MinioFile minioFile = minioFileMapper.getByMd5(md5);
        if (minioFile == null) {
            return "0";
        }
        if (minioFile.getIsComplete() == 1) {
            return "100";
        }
        if (Math.abs(DateUtil.between(minioFile.getUploadTime(), new Date(), DateUnit.HOUR)) < 24) {
            int count = 0;
            for (MinioChunk chunk : minioFile.getChunks()) {
                if (Integer.valueOf(1).equals(chunk.getIsComplete())) {
                    count++;
                }
            }
            return String.valueOf((int)((float) count / minioFile.getChunkCount()) * 100);
            // 没有待上传的,状态还没有合并,则重新上传
        } else {
            return "-1";
        }
    }


    @Override
    public int updateProgrammeFile(ProgrammeFileDto programmeFileDto) {
        String name = programmeFileDto.getName();
        String id = programmeFileDto.getId();
        String tab = programmeFileDto.getTab();
        if (name == null || name.length() == 0) {
            throw new ServiceException("文件名称不可为空");
        }
        if (name.length() < 2 || name.length() > 50) {

        }
        if (id == null || id.length() == 0) {
            throw new ServiceException("修改id不可为空");
        }

        ProgrammeFile programmeFile = programmeFileMapper.selectById(id);
        if (programmeFile == null) {
            throw new ServiceException("修改失败，文件不存在");
        }
        programmeFile.setName(name);
        programmeFile.setUpdateTime(new Date());
        programmeFile.setTab(tab);

        return programmeFileMapper.updateById(programmeFile);

    }

    @Override
    public Long[] queryMinioFileIds(String[] minioFileMd5Str) {
        if (minioFileMd5Str == null || minioFileMd5Str.length == 0) {
            throw new ServiceException("该条基因组数据没有文件");
        }
        List<Long> ids = new ArrayList<>();
        for (String md5 : minioFileMd5Str) {
            MinioFile minioFile = minioFileMapper.getByMd5(md5);
            if (minioFile == null || minioFile.getIsComplete() == 0) {
                throw new ServiceException("该条基因组数据中文件已被清空，请重新上传");
            }
            ids.add(minioFile.getId());
        }
        return ids.toArray(new Long[ids.size()]);
    }

    @Override
    public List<ProgrammeFile> queryUploadFileList(ProgrammeFileQueryParam queryParams) {
        String name = queryParams.getName();
        String userId = SecurityUtils.getUserId();
        queryParams.setCreateBy(userId);
        if (StringUtils.hasLength(name)) {
            queryParams.setName(name.trim());
        }
        return programmeFileMapper.queryUploadFileList(queryParams);
    }
//
//    @Override
//    public Boolean checkName(String genomeDataName, String id) {
//        QueryWrapper<GenomeData> wrapper = new QueryWrapper<GenomeData>()
//                .eq("name", genomeDataName)
//                .eq("create_by", SecurityUtils.getUserId());
//        //编辑弹窗不校验本身
//        if(id!=null){
//            wrapper.ne("id", id);
//        }
//        Long count = genomeDataMapper.selectCount(wrapper);
//        if(count == null || count == 0L){
//            return  false;
//        }
//        return true;
//    }
//
//    @Override
//    public String insertGenomeDataDto(GenomeDataDto genomeDataDto) {
//        List<Map<String,String>> md5s = genomeDataDto.getMd5s();
//        String genomeDataName = genomeDataDto.getName();
//        String type = genomeDataDto.getType();
//        Integer size = genomeDataDto.getSize();
//        Integer count = genomeDataDto.getCount();
//        if(md5s==null){
//            throw new ServiceException("请上传文件");
//        }
//        String mdsStr= "";
//        for (int i = 0; i < md5s.size(); i++) {
//            mdsStr+=md5s.get(i).get("md5")+",";
//        }
//        //去掉最后的逗号
//        if(mdsStr.length()>0){
//            mdsStr=mdsStr.substring(0,mdsStr.length()-1);
//        }
//        if (genomeDataName==null||genomeDataName.length()==0){
//            throw new ServiceException("请填写基因组数据名称");
//        }
//        if(!"1".equals(type)&&!"2".equals(type)&&!"3".equals(type)&&!"4".equals(type)){
//            throw new ServiceException("上传文件类型组合错误");
//        }
//        if(size<1||count<1){
//            throw new ServiceException("请上传文件");
//        }
//        GenomeData genomeData = new GenomeData();
//        genomeData.setName(genomeDataName);
//        genomeData.setCount(count);
//        genomeData.setType(type);
//        genomeData.setCreateTime(new Date());
//        genomeData.setUpdateTime(new Date());
//        // 上传中状态
//        genomeData.setStatus(1);
//        genomeData.setSize(size);
//        genomeData.setMinioFileMd5Str(mdsStr);
//        genomeData.setCreateBy(SecurityUtils.getUserId());
//        genomeDataMapper.insert(genomeData);
//        QueryWrapper<GenomeData> queryWrapper = new QueryWrapper<>();
//        queryWrapper.eq("name",genomeDataName );
//        String genomeDataId = genomeDataMapper.selectOne(queryWrapper).getId();
//
//        for (int i = 0; i < md5s.size(); i++) {
//            programmeFileMinioMapper.insert(
//                    new ProgrammeFlieMinio().setProgrammeFileId(genomeDataId)
//                            .setMinioMd5(md5s.get(i).get("md5"))
//                            .setFileName(md5s.get(i).get("fileName"))
//            );
//        }
//
//        return genomeDataId;
//
//    }
//
//    @Override
//    public List<String> queryFileList(String minioIdStr) {
//        //minio的文件名前面拼接了字符串，以“-”分隔
//        String separator = "-";
//        if(minioIdStr==null||minioIdStr.length()==0){
//            throw new ServiceException("该条基因组数据没有文件");
//        }
//        String[] minioIds = minioIdStr.split(",");
//        List<String> minioNames=new ArrayList<>();
//        for (String minioId : minioIds) {
//            MinioFile minioFile = minioFileMapper.selectById(minioId);
//            if (minioFile==null){
//                throw new ServiceException("该条基因组数据中文件已被清空，请重新上传");
//            }
//            //找到第一个“-”index
//            int indexOfSeparator=minioFile.getFileName().indexOf(separator);
//            //只取file_name列的后半部分
//            minioNames.add(minioFile.getFileName().substring(indexOfSeparator + separator.length()));
//        }
//        return minioNames;
//    }
//
//    @Override
//    public int updateGenomeData(GenomeDataDto genomeDataDto) {
//        String name = genomeDataDto.getName();
//        String id = genomeDataDto.getId();
//        String type = genomeDataDto.getType();
//        Integer count = genomeDataDto.getCount();
//        List<Map<String, String>> md5s = genomeDataDto.getMd5s();
//        Integer size = genomeDataDto.getSize();
//
//        if (name==null||name.length()==0){
//            throw new ServiceException("基因组数据名称不可为空");
//        }
//        if(name.length()<2||name.length()>50){
//            throw new ServiceException("基因组数据名称不合法，请重新输入");
//        }
//        if(id==null||id.length()==0){
//            throw new ServiceException("修改id不可为空");
//        }
//
//        GenomeData genomeData = genomeDataMapper.selectById(id);
//        if (genomeData==null){
//            throw new ServiceException("修改失败，基因组数据不存在");
//        }
//        genomeData.setName(name);
//        genomeData.setUpdateTime(new Date());
//        //可能只修改了名称，传md5了才验证其他属性
//        if (md5s!=null){
//            if(!"1".equals(type)&&!"2".equals(type)&&!"3".equals(type)&&!"4".equals(type)){
//                throw new ServiceException("上传文件类型组合错误");
//            }
//            if(size<1||count<1){
//                throw new ServiceException("请上传文件");
//            }
//            String mdsStr= "";
//            for (int i = 0; i < md5s.size(); i++) {
//                mdsStr+=md5s.get(i).get("md5")+",";
//            }
//            // 上传中状态
//            genomeData.setStatus(1);
//            genomeData.setSize(size);
//            genomeData.setCount(count);
//            genomeData.setType(type);
//            genomeData.setMinioFileMd5Str(mdsStr);
//        }
//
//        return genomeDataMapper.updateById(genomeData);
//    }
//
//    @Override
//    public int updateGenomeDataStatus(Map<String,String> map) {
//        String id = map.get("id");
//        String s = map.get("status");
//        Integer status = Integer.valueOf(s);
//        if(id==null||id.length()==0){
//            throw new ServiceException("id不能为空");
//        }
//        if(status==null|| (status!=1&&status!=2&&status!=3)){
//            throw new ServiceException("请输入正确的状态");
//        }
//        GenomeData genomeData = genomeDataMapper.selectById(id);
//        genomeData.setStatus(status);
//        return genomeDataMapper.updateById(genomeData);
//    }
//


}
